set python environment
do_installs = True
if do_installs:
!pip install acoustics
!pip install numpy
!pip install scipy
!pip install matplotlib
!pip install mne
!pip install pandas
!pip install tensorpac
!pip install requests
!pip install h5py
!pip install spikeinterface
!pip install probeinterface
!pip install tridesclous
!pip install ipython
!pip install ipympl
Requirement already satisfied: acoustics in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (0.2.4.post0) Requirement already satisfied: pandas>=0.15 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (1.3.4) Requirement already satisfied: matplotlib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (3.4.3) Requirement already satisfied: scipy>=0.16 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (1.7.1) Requirement already satisfied: six>=1.4.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (1.16.0) Requirement already satisfied: tabulate in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (0.8.9) Requirement already satisfied: numpy>=1.8 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from acoustics) (1.20.3) Requirement already satisfied: python-dateutil>=2.7.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas>=0.15->acoustics) (2.8.2) Requirement already satisfied: pytz>=2017.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas>=0.15->acoustics) (2021.3) Requirement already satisfied: pyparsing>=2.2.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->acoustics) (3.0.4) Requirement already satisfied: kiwisolver>=1.0.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->acoustics) (1.3.1) Requirement already satisfied: cycler>=0.10 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->acoustics) (0.10.0) Requirement already satisfied: pillow>=6.2.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->acoustics) (8.4.0) Requirement already satisfied: numpy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (1.20.3) Requirement already satisfied: scipy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (1.7.1) Requirement already satisfied: numpy<1.23.0,>=1.16.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from scipy) (1.20.3) Requirement already satisfied: matplotlib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (3.4.3) Requirement already satisfied: cycler>=0.10 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (0.10.0) Requirement already satisfied: kiwisolver>=1.0.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (1.3.1) Requirement already satisfied: pillow>=6.2.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (8.4.0) Requirement already satisfied: python-dateutil>=2.7 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (2.8.2) Requirement already satisfied: pyparsing>=2.2.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (3.0.4) Requirement already satisfied: numpy>=1.16 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib) (1.20.3) Requirement already satisfied: six in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from cycler>=0.10->matplotlib) (1.16.0) Requirement already satisfied: mne in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (1.0.2) Requirement already satisfied: numpy>=1.15.4 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (1.20.3) Requirement already satisfied: matplotlib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (3.4.3) Requirement already satisfied: packaging in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (21.0) Requirement already satisfied: decorator in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (5.1.0) Requirement already satisfied: tqdm in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (4.62.3) Requirement already satisfied: pooch>=1.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (1.6.0) Requirement already satisfied: scipy>=1.1.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (1.7.1) Requirement already satisfied: jinja2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from mne) (2.11.3) Requirement already satisfied: appdirs>=1.3.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pooch>=1.5->mne) (1.4.4) Requirement already satisfied: requests>=2.19.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pooch>=1.5->mne) (2.26.0) Requirement already satisfied: pyparsing>=2.0.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from packaging->mne) (3.0.4) Requirement already satisfied: idna<4,>=2.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests>=2.19.0->pooch>=1.5->mne) (3.2) Requirement already satisfied: charset-normalizer~=2.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests>=2.19.0->pooch>=1.5->mne) (2.0.4) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests>=2.19.0->pooch>=1.5->mne) (1.26.7) Requirement already satisfied: certifi>=2017.4.17 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests>=2.19.0->pooch>=1.5->mne) (2021.10.8) Requirement already satisfied: MarkupSafe>=0.23 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jinja2->mne) (1.1.1) Requirement already satisfied: cycler>=0.10 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->mne) (0.10.0) Requirement already satisfied: pillow>=6.2.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->mne) (8.4.0) Requirement already satisfied: kiwisolver>=1.0.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->mne) (1.3.1) Requirement already satisfied: python-dateutil>=2.7 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->mne) (2.8.2) Requirement already satisfied: six in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from cycler>=0.10->matplotlib->mne) (1.16.0) Requirement already satisfied: pandas in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (1.3.4) Requirement already satisfied: python-dateutil>=2.7.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas) (2.8.2) Requirement already satisfied: pytz>=2017.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas) (2021.3) Requirement already satisfied: numpy>=1.17.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas) (1.20.3) Requirement already satisfied: six>=1.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from python-dateutil>=2.7.3->pandas) (1.16.0) Requirement already satisfied: tensorpac in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (0.6.5) Requirement already satisfied: scipy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tensorpac) (1.7.1) Requirement already satisfied: joblib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tensorpac) (1.1.0) Requirement already satisfied: numpy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tensorpac) (1.20.3) Requirement already satisfied: requests in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (2.26.0) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests) (1.26.7) Requirement already satisfied: idna<4,>=2.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests) (3.2) Requirement already satisfied: charset-normalizer~=2.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests) (2.0.4) Requirement already satisfied: certifi>=2017.4.17 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from requests) (2021.10.8) Requirement already satisfied: h5py in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (3.3.0) Requirement already satisfied: numpy>=1.19.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from h5py) (1.20.3) Requirement already satisfied: spikeinterface in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (0.94.0) Requirement already satisfied: neo>=0.10.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from spikeinterface) (0.10.2) Requirement already satisfied: numpy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from spikeinterface) (1.20.3) Requirement already satisfied: probeinterface>=0.2.9 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from spikeinterface) (0.2.9) Requirement already satisfied: joblib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from spikeinterface) (1.1.0) Requirement already satisfied: tqdm in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from spikeinterface) (4.62.3) Requirement already satisfied: quantities>=0.12.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from neo>=0.10.2->spikeinterface) (0.13.0) Requirement already satisfied: probeinterface in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (0.2.9) Requirement already satisfied: numpy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from probeinterface) (1.20.3) Requirement already satisfied: tridesclous in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (1.6.5) Requirement already satisfied: openpyxl in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (3.0.9) Requirement already satisfied: matplotlib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (3.4.3) Requirement already satisfied: loky in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (3.1.0) Requirement already satisfied: pandas in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (1.3.4) Requirement already satisfied: scipy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (1.7.1) Requirement already satisfied: seaborn in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.11.2) Requirement already satisfied: hdbscan in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.8.28) Requirement already satisfied: tqdm in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (4.62.3) Requirement already satisfied: numpy<1.22 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (1.20.3) Requirement already satisfied: neo>=0.8 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.10.2) Requirement already satisfied: numba in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.54.1) Requirement already satisfied: pyqtgraph in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.12.4) Requirement already satisfied: joblib in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (1.1.0) Requirement already satisfied: scikit-learn>=0.22.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from tridesclous) (0.24.2) Requirement already satisfied: quantities>=0.12.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from neo>=0.8->tridesclous) (0.13.0) Requirement already satisfied: threadpoolctl>=2.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from scikit-learn>=0.22.2->tridesclous) (2.2.0) Requirement already satisfied: cython>=0.27 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from hdbscan->tridesclous) (0.29.24) Requirement already satisfied: cloudpickle in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from loky->tridesclous) (2.0.0) Requirement already satisfied: python-dateutil>=2.7 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->tridesclous) (2.8.2) Requirement already satisfied: kiwisolver>=1.0.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->tridesclous) (1.3.1) Requirement already satisfied: pyparsing>=2.2.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->tridesclous) (3.0.4) Requirement already satisfied: cycler>=0.10 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->tridesclous) (0.10.0) Requirement already satisfied: pillow>=6.2.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib->tridesclous) (8.4.0) Requirement already satisfied: six in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from cycler>=0.10->matplotlib->tridesclous) (1.16.0) Requirement already satisfied: llvmlite<0.38,>=0.37.0rc1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from numba->tridesclous) (0.37.0) Requirement already satisfied: setuptools in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from numba->tridesclous) (58.0.4) Requirement already satisfied: et-xmlfile in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from openpyxl->tridesclous) (1.1.0) Requirement already satisfied: pytz>=2017.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pandas->tridesclous) (2021.3) Requirement already satisfied: ipython in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (7.29.0) Requirement already satisfied: pickleshare in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (0.7.5) Requirement already satisfied: setuptools>=18.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (58.0.4) Requirement already satisfied: traitlets>=4.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (5.1.0) Requirement already satisfied: pygments in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (2.10.0) Requirement already satisfied: matplotlib-inline in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (0.1.2) Requirement already satisfied: backcall in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (0.2.0) Requirement already satisfied: pexpect>4.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (4.8.0) Requirement already satisfied: decorator in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (5.1.0) Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (3.0.20) Requirement already satisfied: jedi>=0.16 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython) (0.18.0) Requirement already satisfied: parso<0.9.0,>=0.8.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jedi>=0.16->ipython) (0.8.2) Requirement already satisfied: ptyprocess>=0.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pexpect>4.3->ipython) (0.7.0) Requirement already satisfied: wcwidth in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython) (0.2.5) Requirement already satisfied: ipympl in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (0.9.1) Requirement already satisfied: ipython-genutils in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (0.2.0) Requirement already satisfied: matplotlib<4,>=3.4.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (3.4.3) Requirement already satisfied: pillow in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (8.4.0) Requirement already satisfied: ipython<9 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (7.29.0) Requirement already satisfied: ipywidgets<8,>=7.6.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (7.6.5) Requirement already satisfied: traitlets<6 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (5.1.0) Requirement already satisfied: numpy in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipympl) (1.20.3) Requirement already satisfied: pygments in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (2.10.0) Requirement already satisfied: pexpect>4.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (4.8.0) Requirement already satisfied: jedi>=0.16 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (0.18.0) Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (3.0.20) Requirement already satisfied: backcall in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (0.2.0) Requirement already satisfied: pickleshare in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (0.7.5) Requirement already satisfied: decorator in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (5.1.0) Requirement already satisfied: setuptools>=18.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (58.0.4) Requirement already satisfied: matplotlib-inline in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipython<9->ipympl) (0.1.2) Requirement already satisfied: jupyterlab-widgets>=1.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipywidgets<8,>=7.6.0->ipympl) (1.0.0) Requirement already satisfied: widgetsnbextension~=3.5.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipywidgets<8,>=7.6.0->ipympl) (3.5.1) Requirement already satisfied: ipykernel>=4.5.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipywidgets<8,>=7.6.0->ipympl) (6.4.1) Requirement already satisfied: nbformat>=4.2.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipywidgets<8,>=7.6.0->ipympl) (5.1.3) Requirement already satisfied: tornado<7.0,>=4.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (6.1) Requirement already satisfied: debugpy<2.0,>=1.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (1.4.1) Requirement already satisfied: jupyter-client<8.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (6.1.12) Requirement already satisfied: parso<0.9.0,>=0.8.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jedi>=0.16->ipython<9->ipympl) (0.8.2) Requirement already satisfied: pyzmq>=13 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (22.2.1) Requirement already satisfied: jupyter-core>=4.6.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (4.8.1) Requirement already satisfied: python-dateutil>=2.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jupyter-client<8.0->ipykernel>=4.5.1->ipywidgets<8,>=7.6.0->ipympl) (2.8.2) Requirement already satisfied: cycler>=0.10 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib<4,>=3.4.0->ipympl) (0.10.0) Requirement already satisfied: pyparsing>=2.2.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib<4,>=3.4.0->ipympl) (3.0.4) Requirement already satisfied: kiwisolver>=1.0.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from matplotlib<4,>=3.4.0->ipympl) (1.3.1) Requirement already satisfied: six in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from cycler>=0.10->matplotlib<4,>=3.4.0->ipympl) (1.16.0) Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbformat>=4.2.0->ipywidgets<8,>=7.6.0->ipympl) (3.2.0) Requirement already satisfied: pyrsistent>=0.14.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7.6.0->ipympl) (0.18.0) Requirement already satisfied: attrs>=17.4.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat>=4.2.0->ipywidgets<8,>=7.6.0->ipympl) (21.2.0) Requirement already satisfied: ptyprocess>=0.5 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from pexpect>4.3->ipython<9->ipympl) (0.7.0) Requirement already satisfied: wcwidth in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython<9->ipympl) (0.2.5) Requirement already satisfied: notebook>=4.4.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (6.4.5) Requirement already satisfied: terminado>=0.8.3 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.9.4) Requirement already satisfied: prometheus-client in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.11.0) Requirement already satisfied: nbconvert in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (6.1.0) Requirement already satisfied: jinja2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (2.11.3) Requirement already satisfied: argon2-cffi in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (20.1.0) Requirement already satisfied: Send2Trash>=1.5.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.8.0) Requirement already satisfied: cffi>=1.0.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.14.6) Requirement already satisfied: pycparser in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from cffi>=1.0.0->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (2.20) Requirement already satisfied: MarkupSafe>=0.23 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from jinja2->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.1.1) Requirement already satisfied: mistune<2,>=0.8.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.8.4) Requirement already satisfied: bleach in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (4.0.0) Requirement already satisfied: testpath in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.5.0) Requirement already satisfied: defusedxml in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.7.1) Requirement already satisfied: nbclient<0.6.0,>=0.5.0 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.5.3) Requirement already satisfied: entrypoints>=0.2.2 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.3) Requirement already satisfied: jupyterlab-pygments in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.1.2) Requirement already satisfied: pandocfilters>=1.4.1 in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.4.3) Requirement already satisfied: async-generator in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbclient<0.6.0,>=0.5.0->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.10) Requirement already satisfied: nest-asyncio in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from nbclient<0.6.0,>=0.5.0->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (1.5.1) Requirement already satisfied: packaging in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (21.0) Requirement already satisfied: webencodings in /home/simon/anaconda3/envs/teaching_env/lib/python3.9/site-packages (from bleach->nbconvert->notebook>=4.4.1->widgetsnbextension~=3.5.0->ipywidgets<8,>=7.6.0->ipympl) (0.5.1)
import acoustics #=> for creating artificial signals
import numpy as np #=> for numeric operations
import scipy as sc #=> for scientific computing
import matplotlib.pyplot as plt #=> for plotting
import mne #=> for signal processing (M/EEG)
# set browser backend to matplotlib => no popup
mne.viz.set_browser_backend('matplotlib')
import copy #=> deepcopying
import pandas as pd #=> for working with data frames
import requests #=> for downloading data from the web
import h5py #=> for importing *.h5-files
%matplotlib inline
#=> set plotting backend for notebooks
Using matplotlib as 2D backend.
Once the signal is cleaned, we can extract specific features that can be used for further analyses (e.g. machine learning, or statistical testing)
Possible relevant features (to be discussed in the lecture):
Here, we can only touch a few features.
For examples, see previous practical
Definition: in time-frequency analyses, the signal in the time domain is transformed into the frequency domain for short subsegements of the original signal. This allows exploring how the spectral composition of the signal varies across time.
Basic principle:
Create an artificial signal:
#%% Create artificial data
ieeg = {}
ieeg['srate'] = 1000
ieeg['dur'] = 5
ieeg['time'] = np.arange(0,ieeg['dur']*ieeg['srate'])/ieeg['srate']
ieeg['data'] = []
ieeg['type'] = []
# add some pink-noise
ieeg['type'].append('ieeg')
ieeg['data'].append(acoustics.generator.noise(
N=len(ieeg['time']), # 10`000 samples
color='pink',
state=np.random.RandomState(seed=2022) # seed for random numbers generator
))
# add 10 Hz sine wave burst
ieeg['data'][0][
(ieeg['time']>2) & (ieeg['time']<3)] = \
ieeg['data'][0][(ieeg['time']>2) & (ieeg['time']<3)] +\
5*np.sin(ieeg['time'][(ieeg['time']>2) & (ieeg['time']<3)]*2*np.pi*10)
# add 20 Hz fixed wave
ieeg['data'][0] = ieeg['data'][0] + 2*np.sin(ieeg['time']*2*np.pi*20)
# add a chirp that linearly increases with frequency
ieeg['data'][0] = ieeg['data'][0] + 2*np.sin(ieeg['time']*2*np.pi*(20+2*ieeg['time']))
Plot the artificial signal
fig, ax = plt.subplots(figsize=(15,5))
ax.plot(ieeg['time'],
ieeg['data'][0])
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.grid()
Perform the time-frequency decomposition:
# Decompose the signal
ieeg['tfr_freqs'] = np.arange(1,50) # Frequency resolution of the decomposition
ieeg['tfr_ncycles'] = ieeg['tfr_freqs']/2 # Number of cycles (length of window) for which to compute the power at each frequency
ieeg['tfr'] = mne.time_frequency.tfr_array_morlet(
epoch_data = ieeg['data'][0][np.newaxis,np.newaxis,:],
sfreq = ieeg['srate'],
freqs= ieeg['tfr_freqs'],
n_cycles=ieeg['tfr_ncycles'])
Plot the decomposition
# Plot the decomosition
fig, ax = plt.subplots(figsize= (15,5))
img = ax.pcolormesh(
ieeg['time'],
ieeg['tfr_freqs'],
np.abs(np.squeeze(ieeg['tfr'])))
ax.set_ylabel('Frequency (Hz)')
ax.set_xlabel('Time (s)')
cb = plt.colorbar(img, ax=ax)
cb.set_label('Power')
/tmp/ipykernel_11717/764831586.py:4: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later. img = ax.pcolormesh(
ASSIGNMENT:
# ASSIGNMENT:
# => hint: modify the following elements of the above code:
# ieeg['tfr_freqs'] = ...
# ieeg['tfr_ncycles'] = ...
Download intracranial eeg data from Fedele et al., 2017, Scientific Reports.
Use MNE to process the data:
import requests
# Dataset: events
url = "https://openneuro.org/crn/datasets/ds003498/snapshots/1.0.1/files/sub-01:ses-interictalsleep:ieeg:sub-01_ses-interictalsleep_run-01_events.tsv"
r = requests.get(url, allow_redirects=True)
open('sub-01_ses-interictalsleep_run-01_events.tsv', 'wb').write(r.content)
# Dataset: channel info
url = "https://openneuro.org/crn/datasets/ds003498/snapshots/1.0.1/files/sub-01:ses-interictalsleep:ieeg:sub-01_ses-interictalsleep_run-01_channels.tsv"
r = requests.get(url, allow_redirects=True)
open('sub-01_ses-interictalsleep_run-01_channels.tsv', 'wb').write(r.content)
# Dataset: header
url = "https://openneuro.org/crn/datasets/ds003498/snapshots/1.0.1/files/sub-01:ses-interictalsleep:ieeg:sub-01_ses-interictalsleep_run-01_ieeg.vhdr"
r = requests.get(url, allow_redirects=True)
open('sub-01_ses-interictalsleep_run-01_ieeg.vhdr', 'wb').write(r.content)
# Dataset: marker
url = "https://openneuro.org/crn/datasets/ds003498/snapshots/1.0.1/files/sub-01:ses-interictalsleep:ieeg:sub-01_ses-interictalsleep_run-01_ieeg.vmrk"
r = requests.get(url, allow_redirects=True)
open('sub-01_ses-interictalsleep_run-01_ieeg.vmrk', 'wb').write(r.content)
# Dataset: eeg
url = "https://openneuro.org/crn/datasets/ds003498/snapshots/1.0.1/files/sub-01:ses-interictalsleep:ieeg:sub-01_ses-interictalsleep_run-01_ieeg.eeg"
r = requests.get(url, allow_redirects=True)
open('sub-01_ses-interictalsleep_run-01_ieeg.eeg', 'wb').write(r.content)
120000000
Import the data using mne:
ieeg = mne.io.read_raw_brainvision('sub-01_ses-interictalsleep_run-01_ieeg.vhdr',preload=True)
ieeg.annotations.crop(0,0)
ieeg.info
Extracting parameters from sub-01_ses-interictalsleep_run-01_ieeg.vhdr... Setting channel info structure... Reading 0 ... 599999 = 0.000 ... 300.000 secs...
/tmp/ipykernel_11717/3922152492.py:1: RuntimeWarning: Limited 1 annotation(s) that were expanding outside the data range.
ieeg = mne.io.read_raw_brainvision('sub-01_ses-interictalsleep_run-01_ieeg.vhdr',preload=True)
| Measurement date | December 07, 2013 08:29:20 GMT |
|---|---|
| Experimenter | Unknown | Participant | Unknown |
| Digitized points | 0 points |
| Good channels | 50 EEG |
| Bad channels | None |
| EOG channels | Not available |
| ECG channels | Not available |
| Sampling frequency | 2000.00 Hz |
| Highpass | 0.00 Hz |
| Lowpass | 1000.00 Hz |
Plot first 10 s of raw data of all channels
# set browser backend to matplotlib => no popup
mne.viz.set_browser_backend('matplotlib')
'matplotlib'
# Plot data
fig = mne.viz.plot_raw(
ieeg,
duration=10.0,
start=0.0,
n_channels=50,
show=False,
scalings={'eeg':0.0001})
fig.set_size_inches(15,10)
Opening raw-browser...
Keep only data from macroelectrodes targeting the left amydgala (AL1-8)
ieeg_AL = ieeg.copy().pick_channels(['AL1','AL2','AL3','AL4','AL5','AL6','AL7','AL8'])
Drop channel "AL8":
ieeg_AL.drop_channels('AL8')
| Measurement date | December 07, 2013 08:29:20 GMT |
|---|---|
| Experimenter | Unknown | Participant | Unknown |
| Digitized points | 0 points |
| Good channels | 7 EEG |
| Bad channels | None |
| EOG channels | Not available |
| ECG channels | Not available |
| Sampling frequency | 2000.00 Hz |
| Highpass | 0.00 Hz |
| Lowpass | 1000.00 Hz |
| Filenames | sub-01_ses-interictalsleep_run-01_ieeg.eeg |
| Duration | 00:04:59 (HH:MM:SS) |
Re-reference the EEG to the common average of all channels:
ieeg_AL.set_eeg_reference(ref_channels='average')
EEG channel type selected for re-referencing
Applying average reference.
Applying a custom ('EEG',) reference.
| Measurement date | December 07, 2013 08:29:20 GMT |
|---|---|
| Experimenter | Unknown | Participant | Unknown |
| Digitized points | 0 points |
| Good channels | 7 EEG |
| Bad channels | None |
| EOG channels | Not available |
| ECG channels | Not available |
| Sampling frequency | 2000.00 Hz |
| Highpass | 0.00 Hz |
| Lowpass | 1000.00 Hz |
| Filenames | sub-01_ses-interictalsleep_run-01_ieeg.eeg |
| Duration | 00:04:59 (HH:MM:SS) |
Plot re-referenced data from left amydgala
# Plot data
fig = mne.viz.plot_raw(
ieeg_AL,
duration=10.0,
start=0.0,
n_channels=50,
show=False,
scalings={'eeg':0.0001})
fig.set_size_inches(15,10)
Opening raw-browser...
Plot PSD for rereferenced data from left amygdala
fig = ieeg_AL.plot_psd(
n_fft = int(2*ieeg_AL.info.get('sfreq')), # => length of segments: 2* sampling frequency
n_overlap = int(0.9*2*ieeg_AL.info.get('sfreq')), # => overlap of segments: 0.9 (90%) of 2s windows
show=False
)
fig.set_size_inches(15,5)
Effective window size : 2.000 (s)
/tmp/ipykernel_11717/1402638186.py:1: RuntimeWarning: Channel locations not available. Disabling spatial colors. fig = ieeg_AL.plot_psd(
Subset data:
ieeg_AL1_window = ieeg_AL.copy().pick_channels(['AL1']).crop(30,60)
Perform the time-frequency decomposition on real data from Amydgala channel AL1:
# Decompose the signal
AL_dat = {}
AL_dat['tfr_freqs'] = np.arange(1,80,0.5) # Frequency resolution of the decomposition
AL_dat['tfr_ncycles'] = AL_dat['tfr_freqs']/2 # Number of cycles (length of window) for which to compute the power at each frequency
AL_dat['tfr'] = mne.time_frequency.tfr_array_morlet(
epoch_data = ieeg_AL1_window.get_data()[np.newaxis,:],
sfreq = ieeg_AL1_window.info.get('sfreq'),
freqs= AL_dat['tfr_freqs'],
n_cycles=AL_dat['tfr_ncycles'],
output='power')
# Normalize data
AL_dat['tfr'] = np.squeeze(AL_dat['tfr'])
#AL_dat['tfr'] = np.log10(np.squeeze(AL_dat['tfr']))
AL_dat['tfr_mean'] = np.mean(AL_dat['tfr'],axis=1)
AL_dat['tfr_std'] = np.std(AL_dat['tfr'],axis=1)
AL_dat['tfr_stdnorm'] = (AL_dat['tfr']-AL_dat['tfr_mean'][:,None])/AL_dat['tfr_std'][:,None]
AL_dat['tfr_md'] = np.median(AL_dat['tfr'],axis=1)
AL_dat['tfr_mad'] = np.median(np.abs(AL_dat['tfr']-AL_dat['tfr_md'][:,None]),axis = 1)
AL_dat['tfr_madnorm'] = (AL_dat['tfr']-AL_dat['tfr_md'][:,None])/AL_dat['tfr_mad'][:,None]
Plot the decomposition, compare it with the signal in the time domain
# Plot the decomposition
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, ax = plt.subplots(nrows = 2, sharex=True, figsize= (15,5))
img = ax[0].pcolormesh(
ieeg_AL1_window.times,
AL_dat['tfr_freqs'],
np.squeeze(AL_dat['tfr_stdnorm']),
vmin=-2,
vmax=2)
ax[0].set_ylabel('Frequency (Hz)')
ax[0].set_xlim(0,5)
axins = inset_axes(ax[0],
width="5%",
height="50%",
loc='upper right')
cb = plt.colorbar(img, cax=axins)
cb.set_label('Power')
ax[1].plot(ieeg_AL1_window.times,ieeg_AL1_window.get_data().T)
ax[1].set_ylabel('Amplitude')
ax[1].set_xlabel('Time (s)')
/tmp/ipykernel_11717/4103540333.py:7: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later. img = ax[0].pcolormesh(
Text(0.5, 0, 'Time (s)')
Assignment: change plot to focus on shorter window and smaller frequency band (e.g. 0-5s, 0-20 Hz)
#Assignment hint: use ax[0].set_xlim() amd ax[0].set_ylim()
Definition: Analysis of the time-resolved (i.e., instantaneous) power and phase of a signal in a specific frequency band.
Possible aplications:
Create an artificial signal:
#%% Create artificial data
ieeg = {}
ieeg['srate'] = 1000
ieeg['dur'] = 5
ieeg['time'] = np.arange(0,ieeg['dur']*ieeg['srate'])/ieeg['srate']
ieeg['data'] = []
ieeg['type'] = []
# add some pink-noise
ieeg['type'].append('ieeg')
ieeg['data'].append(acoustics.generator.noise(
N=len(ieeg['time']), # 10`000 samples
color='pink',
state=np.random.RandomState(seed=2022) # seed for random numbers generator
))
# add 10 Hz sine wave burst
ieeg['data'][0][
(ieeg['time']>2) & (ieeg['time']<3)] = \
ieeg['data'][0][(ieeg['time']>2) & (ieeg['time']<3)] +\
5*np.sin(ieeg['time'][(ieeg['time']>2) & (ieeg['time']<3)]*2*np.pi*10)
# add 4 Hz fixed wave
ieeg['data'][0] = ieeg['data'][0] + 2*np.sin(ieeg['time']*2*np.pi*2)
# add a chirp that linearly increases with frequency
ieeg['data'][0] = ieeg['data'][0] + 2*np.sin(ieeg['time']*2*np.pi*20)*(1+np.sin(ieeg['time']*2*np.pi*2))
Plot the artificial signal
fig, ax = plt.subplots(figsize=(15,5))
ax.plot(ieeg['time'],
ieeg['data'][0])
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.grid()
Perform the time-frequency decomposition:
# Decompose the signal
ieeg['tfr_freqs'] = np.arange(1,50) # Frequency resolution of the decomposition
ieeg['tfr_ncycles'] = ieeg['tfr_freqs']/2 # Number of cycles (length of window) for which to compute the power at each frequency
ieeg['tfr'] = mne.time_frequency.tfr_array_morlet(
epoch_data = ieeg['data'][0][np.newaxis,np.newaxis,:],
sfreq = ieeg['srate'],
freqs= ieeg['tfr_freqs'],
n_cycles=ieeg['tfr_ncycles'])
Plot the decomposition
# Plot the decomosition
fig, ax = plt.subplots(figsize= (15,5))
img = ax.pcolormesh(
ieeg['time'],
ieeg['tfr_freqs'],
np.abs(np.squeeze(ieeg['tfr'])))
ax.set_ylabel('Frequency (Hz)')
ax.set_xlabel('Time (s)')
cb = plt.colorbar(img, ax=ax)
cb.set_label('Power')
/tmp/ipykernel_11717/764831586.py:4: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later. img = ax.pcolormesh(
Pefrorm the hilbert transform for 20 Hz oscillations:
#%% Hilbert decomposition
sgn_raw = ieeg['data'][0]
sgn_filt = mne.filter.filter_data(sgn_raw,
sfreq=ieeg['srate'],
l_freq = 18,
h_freq = 22)
sgn_hilb20 = sc.signal.hilbert(x=sgn_filt)
Setting up band-pass filter from 18 - 22 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 18.00 - Lower transition bandwidth: 4.50 Hz (-6 dB cutoff frequency: 15.75 Hz) - Upper passband edge: 22.00 Hz - Upper transition bandwidth: 5.50 Hz (-6 dB cutoff frequency: 24.75 Hz) - Filter length: 735 samples (0.735 sec)
Plot the hilbert transform
fig, ax = plt.subplots(nrows = 2,figsize=(15,10))
ax[0].plot(ieeg['time'],sgn_raw, label='raw')
ax[0].plot(ieeg['time'],sgn_filt,label='bandpass filtered')
ax[0].plot(ieeg['time'],np.abs(sgn_hilb20),label='hilbert envelope',color='g')
ax[0].legend()
ax[0].grid()
ax[1].set_ylabel('Amplitude')
ax[1].plot(ieeg['time'],np.angle(sgn_hilb20),color='g')
ax[1].set_ylabel('Phase')
ax[1].grid()
Pefrorm the hilbert transform for 2 Hz oscillations:
#%% Hilbert decomposition
sgn_raw = ieeg['data'][0]
sgn_filt = mne.filter.filter_data(sgn_raw,
sfreq=ieeg['srate'],
l_freq = 1,
h_freq = 3)
sgn_hilb2 = sc.signal.hilbert(x=sgn_filt)
Setting up band-pass filter from 1 - 3 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 1.00 - Lower transition bandwidth: 1.00 Hz (-6 dB cutoff frequency: 0.50 Hz) - Upper passband edge: 3.00 Hz - Upper transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 4.00 Hz) - Filter length: 3301 samples (3.301 sec)
Plot the hilbert transform
fig, ax = plt.subplots(nrows = 2,figsize=(15,10))
ax[0].plot(ieeg['time'],sgn_raw, label='raw')
ax[0].plot(ieeg['time'],sgn_filt,label='bandpass filtered')
ax[0].plot(ieeg['time'],np.abs(sgn_hilb2),label='hilbert envelope',color='g')
ax[0].legend()
ax[0].grid()
ax[1].set_ylabel('Amplitude')
ax[1].plot(ieeg['time'],np.angle(sgn_hilb2),color='g')
ax[1].set_ylabel('Phase')
ax[1].grid()
Phase amplitude-coupling describes the phenomenon that the activity (amplitude) of a higher frequency (e.g. 20 Hz) is coupled to a specific phase (e.g. the peak) of a lower freqeuency oscillation (e.g. 2 Hz). The phase of a low frequency oscillation thus appears to modulate the amplitude of a high-frequency oscillation.
Relevance (see Munia & Aviyente, 2019; https://doi.org/10.1038/s41598-019-48870-2):
Further reading:
Create an artificial signal:
#%% Create artificial data
ieeg = {}
ieeg['srate'] = 1000
ieeg['dur'] = 5
ieeg['time'] = np.arange(0,ieeg['dur']*ieeg['srate'])/ieeg['srate']
ieeg['data'] = []
ieeg['type'] = []
# add some pink-noise
ieeg['type'].append('ieeg')
ieeg['data'].append(acoustics.generator.noise(
N=len(ieeg['time']), # 10`000 samples
color='pink',
state=np.random.RandomState(seed=2022) # seed for random numbers generator
))
# add 10 Hz sine wave burst
ieeg['data'][0][
(ieeg['time']>2) & (ieeg['time']<3)] = \
ieeg['data'][0][(ieeg['time']>2) & (ieeg['time']<3)] +\
5*np.sin(ieeg['time'][(ieeg['time']>2) & (ieeg['time']<3)]*2*np.pi*10)
# add 2 Hz fixed wave
ieeg['data'][0] = ieeg['data'][0] + 2*np.sin(ieeg['time']*2*np.pi*2)
# Add a 20 Hz oscillation that is modulated by the phase of the 2 Hz oscillation
ieeg['data'][0] = (ieeg['data'][0] + # current data
2*np.sin(ieeg['time']*2*np.pi*20)* # 20 Hz sine wave
(1+np.sin(ieeg['time']*2*np.pi*2))) # Multiplied by amplitude of 2 Hz sine wave
Plot the artificial signal
fig, ax = plt.subplots(figsize=(15,5))
ax.plot(ieeg['time'],
ieeg['data'][0])
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.grid()
Perform the hilbert transform for the 20 Hz, 2 Hz, and 10 Hz band
#%% Hilbert decomposition
sgn_raw = ieeg['data'][0]
sgn_filt20 = mne.filter.filter_data(sgn_raw,
sfreq=ieeg['srate'],
l_freq = 18,
h_freq = 22)
sgn_hilb20 = sc.signal.hilbert(x=sgn_filt20)
sgn_filt2 = mne.filter.filter_data(sgn_raw,
sfreq=ieeg['srate'],
l_freq = 1,
h_freq = 3)
sgn_hilb2 = sc.signal.hilbert(x=sgn_filt2)
sgn_filt10 = mne.filter.filter_data(sgn_raw,
sfreq=ieeg['srate'],
l_freq = 8,
h_freq = 12)
sgn_hilb10 = sc.signal.hilbert(x=sgn_filt10)
Setting up band-pass filter from 18 - 22 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 18.00 - Lower transition bandwidth: 4.50 Hz (-6 dB cutoff frequency: 15.75 Hz) - Upper passband edge: 22.00 Hz - Upper transition bandwidth: 5.50 Hz (-6 dB cutoff frequency: 24.75 Hz) - Filter length: 735 samples (0.735 sec) Setting up band-pass filter from 1 - 3 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 1.00 - Lower transition bandwidth: 1.00 Hz (-6 dB cutoff frequency: 0.50 Hz) - Upper passband edge: 3.00 Hz - Upper transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 4.00 Hz) - Filter length: 3301 samples (3.301 sec) Setting up band-pass filter from 8 - 12 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 8.00 - Lower transition bandwidth: 2.00 Hz (-6 dB cutoff frequency: 7.00 Hz) - Upper passband edge: 12.00 Hz - Upper transition bandwidth: 3.00 Hz (-6 dB cutoff frequency: 13.50 Hz) - Filter length: 1651 samples (1.651 sec)
Plot the raw signal, the filtered signal, and the envelopes
fig, ax = plt.subplots(nrows=3, ncols= 1, figsize=(15,15))
ax[0].plot(ieeg['time'],sgn_raw, label='raw')
ax[0].plot(ieeg['time'],sgn_filt2,label='bandpass filtered')
ax[0].plot(ieeg['time'],np.abs(sgn_hilb2),label='hilbert envelope',color='g')
ax[0].legend()
ax[0].grid()
ax[0].set_title('2 Hz oscillation')
ax[1].plot(ieeg['time'],sgn_raw, label='raw')
ax[1].plot(ieeg['time'],sgn_filt10,label='bandpass filtered')
ax[1].plot(ieeg['time'],np.abs(sgn_hilb10),label='hilbert envelope',color='g')
ax[1].legend()
ax[1].grid()
ax[1].set_title('10 Hz oscillation')
ax[2].plot(ieeg['time'],sgn_raw, label='raw')
ax[2].plot(ieeg['time'],sgn_filt20,label='bandpass filtered')
ax[2].plot(ieeg['time'],np.abs(sgn_hilb20),label='hilbert envelope',color='g')
ax[2].legend()
ax[2].grid()
ax[2].set_title('20 Hz oscillation')
fig.tight_layout()
Assess how activity at 10 Hz and 20 Hz is coupled to the 2 Hz phase
Make a data frame with the amplitude values at 10 Hz and 20 Hz and the phase angles at 2 Hz for each sample:
phase_amp_data = pd.DataFrame(
{
'phase2Hz': np.angle(sgn_hilb2),
'amp20Hz':np.abs(sgn_hilb20),
'amp10Hz':np.abs(sgn_hilb10)}
)
Group the phase angles into 24 equally sized bins
phase_amp_data['phase2Hz_bin'] = pd.cut(phase_amp_data['phase2Hz'],24)
phase_amp_data['phase2Hz_bincentres'] = phase_amp_data['phase2Hz_bin'].apply(lambda x: x.mid)
phase_amp_data
| phase2Hz | amp20Hz | amp10Hz | phase2Hz_bin | phase2Hz_bincentres | |
|---|---|---|---|---|---|
| 0 | -1.570796 | 1.858320 | 0.367373 | (-1.832, -1.571] | -1.7015 |
| 1 | -1.555456 | 2.090646 | 0.371470 | (-1.571, -1.309] | -1.4400 |
| 2 | -1.540155 | 2.135187 | 0.363878 | (-1.571, -1.309] | -1.4400 |
| 3 | -1.525022 | 2.229085 | 0.362326 | (-1.571, -1.309] | -1.4400 |
| 4 | -1.509828 | 2.267196 | 0.356706 | (-1.571, -1.309] | -1.4400 |
| ... | ... | ... | ... | ... | ... |
| 4995 | -1.626048 | 1.715370 | 0.430232 | (-1.832, -1.571] | -1.7015 |
| 4996 | -1.612174 | 1.761613 | 0.425062 | (-1.832, -1.571] | -1.7015 |
| 4997 | -1.598442 | 1.762300 | 0.414002 | (-1.832, -1.571] | -1.7015 |
| 4998 | -1.584595 | 1.822797 | 0.407230 | (-1.832, -1.571] | -1.7015 |
| 4999 | -1.570796 | 1.748505 | 0.381812 | (-1.832, -1.571] | -1.7015 |
5000 rows × 5 columns
Compute the mean amplitudes at 10 Hz and 20 Hz for each 2 Hz bin. Normalize the amplitudes in each bin by the sum of of the amplitudes from all bins.
phase_amp_data_aggr = phase_amp_data.groupby('phase2Hz_bincentres').mean().reset_index()
phase_amp_data_aggr['amp10Hz']= phase_amp_data_aggr['amp10Hz']/sum(phase_amp_data_aggr['amp10Hz'])
phase_amp_data_aggr['amp20Hz']= phase_amp_data_aggr['amp20Hz']/sum(phase_amp_data_aggr['amp20Hz'])
phase_amp_data_aggr
| phase2Hz_bincentres | phase2Hz | amp20Hz | amp10Hz | |
|---|---|---|---|---|
| 0 | -3.013500 | -3.011027 | 0.004951 | 0.062912 |
| 1 | -2.748500 | -2.748252 | 0.007916 | 0.051070 |
| 2 | -2.487000 | -2.488079 | 0.013656 | 0.045891 |
| 3 | -2.225000 | -2.225834 | 0.021031 | 0.041093 |
| 4 | -1.963000 | -1.963471 | 0.028762 | 0.037941 |
| 5 | -1.701500 | -1.701149 | 0.037366 | 0.033893 |
| 6 | -1.440000 | -1.439143 | 0.047415 | 0.031967 |
| 7 | -1.178000 | -1.177680 | 0.056267 | 0.029361 |
| 8 | -0.916000 | -0.916871 | 0.064041 | 0.027282 |
| 9 | -0.654000 | -0.655559 | 0.070692 | 0.028848 |
| 10 | -0.392500 | -0.393241 | 0.075847 | 0.029412 |
| 11 | -0.130913 | -0.130344 | 0.078325 | 0.034970 |
| 12 | 0.131087 | 0.131076 | 0.078762 | 0.038151 |
| 13 | 0.393000 | 0.392444 | 0.076363 | 0.043226 |
| 14 | 0.655000 | 0.654758 | 0.071566 | 0.047264 |
| 15 | 0.916500 | 0.915930 | 0.064248 | 0.048677 |
| 16 | 1.178000 | 1.177644 | 0.054907 | 0.048251 |
| 17 | 1.440000 | 1.439873 | 0.044706 | 0.044809 |
| 18 | 1.702000 | 1.701644 | 0.034693 | 0.042457 |
| 19 | 1.963500 | 1.963532 | 0.025246 | 0.040224 |
| 20 | 2.225000 | 2.225965 | 0.017575 | 0.040713 |
| 21 | 2.487000 | 2.487639 | 0.011817 | 0.042762 |
| 22 | 2.749000 | 2.749181 | 0.008045 | 0.048891 |
| 23 | 3.011000 | 3.012978 | 0.005804 | 0.059936 |
Quantify phase amplitude coupling:
Compute the mean vector as complex number:
MI_2hzX10Hz = np.mean(
phase_amp_data_aggr['amp10Hz'].to_numpy()*np.exp(1j*phase_amp_data_aggr['phase2Hz_bincentres'].to_numpy()))
MI_2hzX20Hz = np.mean(
phase_amp_data_aggr['amp20Hz'].to_numpy()*np.exp(1j*phase_amp_data_aggr['phase2Hz_bincentres'].to_numpy()))
Plot amplitudes in each phase on polar coordinate system, add mean vector
fig = plt.figure(figsize=(15,10))
ax = fig.add_subplot(121, projection='polar')
ax.bar(x=phase_amp_data_aggr['phase2Hz_bincentres'],
height=phase_amp_data_aggr['amp20Hz'],
width=2*np.pi/24,
linewidth=2,
edgecolor="white")
ax.plot([0,np.angle(MI_2hzX20Hz)],
[0,np.abs(MI_2hzX20Hz)],'r',linewidth=2)
ax.set_title('Mean 20 Hz amplitude by 2 Hz phase')
ax.set_ylim(0,1/12)
ax = fig.add_subplot(122, projection='polar')
ax.bar(x=phase_amp_data_aggr['phase2Hz_bincentres'],
height= phase_amp_data_aggr['amp10Hz'],
width=2*np.pi/24,
linewidth=2,
edgecolor="white")
ax.plot([0,np.angle(MI_2hzX10Hz)],
[0,np.abs(MI_2hzX10Hz)],'r',linewidth=2)
ax.set_ylim(0,1/12)
ax.set_title('Mean 10 Hz amplitude by 2 Hz phase')
Text(0.5, 1.0, 'Mean 10 Hz amplitude by 2 Hz phase')
The comodulogram illustrates phase-amplitude coupling between phases of an entire range of frequencies (e.g. 1-6 Hz) and amplitudes of an entire range of frequencies (e.g. 7-40 Hz)
The package "tensorpac" (https://etiennecmb.github.io/tensorpac/) provides efficient and robust methods for PAC analyses.
Compute comodulogram for artificial data:
import tensorpac
# Define a Pac object
p = tensorpac.Pac(idpac=(6,0,0), f_pha=(1,6,0.5,0.1), f_amp=(6,40,1,0.5))
# Filter the data and extract pac
xpac = p.filterfit(1000, sgn_raw)
# Prpare figure
fig, ax = plt.subplots(figsize=(15,10))
# plot Phase-Amplitude Coupling :
ax = p.comodulogram(xpac.mean(-1), cmap='Spectral_r', plotas='contour', ncontours=20,
title=r'2hz phase$\Leftrightarrow$20Hz amplitude coupling',
fz_title=14, fz_labels=13)
p.show()
Phase Amplitude Coupling object defined
extract phases (n_pha=45) and amplitudes (n_amps=66)
true PAC estimation using Gaussian Copula PAC (gcPac)
Compute comodulogram data from the Amygdala ('AL1'):
# Define a Pac object
p = tensorpac.Pac(idpac=(6,0,0), f_pha=(1,10,1,1), f_amp=(11,100,1,1))
# Filter the data and extract pac
xpac = p.filterfit(ieeg_AL1_window.info.get('sfreq'), ieeg_AL1_window.get_data(0))
# Prpare figure
fig, ax = plt.subplots(figsize=(15,10))
# plot Phase-Amplitude Coupling :
ax = p.comodulogram(xpac.mean(-1), cmap='Spectral_r', plotas='contour', ncontours=20,
title=r'<10hz phase$\Leftrightarrow$>20Hz amplitude coupling',
fz_title=14, fz_labels=13)
p.show()
Phase Amplitude Coupling object defined
extract phases (n_pha=8) and amplitudes (n_amps=88)
true PAC estimation using Gaussian Copula PAC (gcPac)
Download example data that is used in the tutorials for the (outdated) SpikeSort package
Dataset:
# Donload the data
url = "https://github.com/btel/SpikeSort/releases/download/v0.12/tutorial.h5"
r = requests.get(url, allow_redirects=True)
open('microelectrode_data.h5','wb').write(r.content)
188913976
# Load the dataset
import h5py
# sampling rate: 25000 Hz
# 4 Channels
# 15.675 minutes of recording
f = h5py.File('microelectrode_data.h5')
dset = f['SubjectA']['session01']['el1']['raw'][:]
print('Dimension:')
print(dset.shape)
print('Duration in minutes: ' + str(dset.shape[1]/25000/60))
Dimension: (4, 23512500) Duration in minutes: 15.675
Cut the date to 5 minutes
dset = dset[:,10*60*25000:15*60*25000]
Create a mne dataset
dset_info = mne.create_info(ch_names=['ch0','ch1','ch2','ch3'],ch_types=4*['eeg'], sfreq=25000)
dset_mne = mne.io.RawArray(dset,dset_info)
Creating RawArray with float64 data, n_channels=4, n_times=7500000
Range : 0 ... 7499999 = 0.000 ... 300.000 secs
Ready.
Plot raw data: 5 seconds
# set browser backend to matplotlib => no popup
mne.viz.set_browser_backend('matplotlib')
fig = mne.viz.plot_raw(
dset_mne,
start=0,
duration = 5,
show=False,
scalings={'eeg':1000})
fig.set_size_inches(15,10)
Opening raw-browser...
Plot PSD of raw data
fig = dset_mne.plot_psd(show=False)
fig.set_size_inches(15,10)
Effective window size : 0.082 (s)
/tmp/ipykernel_11717/2290661222.py:1: RuntimeWarning: Channel locations not available. Disabling spatial colors. fig = dset_mne.plot_psd(show=False)
Re-reference the data to common median
dset_mne_ref = mne.io.RawArray(dset[:]-np.median(dset[:],axis=0)[None,:],
dset_info)
Creating RawArray with float64 data, n_channels=4, n_times=7500000
Range : 0 ... 7499999 = 0.000 ... 300.000 secs
Ready.
fig = mne.viz.plot_raw(
dset_mne_ref,
start=0,
duration = 5,
show=False,
scalings={'eeg':1000})
fig.set_size_inches(15,10)
Opening raw-browser...
Plot psd of median referenced data
fig = dset_mne_ref.plot_psd(show=False)
fig.set_size_inches(15,10)
Effective window size : 0.082 (s)
/tmp/ipykernel_11717/729340552.py:1: RuntimeWarning: Channel locations not available. Disabling spatial colors. fig = dset_mne_ref.plot_psd(show=False)
Plot only channel 3, first second
fig = mne.viz.plot_raw(
dset_mne_ref.copy().pick_channels(['ch3']),
start=0,
duration = 1,
show=False,
scalings={'eeg':1000})
fig.set_size_inches(15,5)
Opening raw-browser...
Plot only channel 3, 80-100 ms
fig = mne.viz.plot_raw(
dset_mne_ref.copy().pick_channels(['ch3']),
start=0.08,
duration = 0.02,
show=False,
scalings={'eeg':1000})
fig.set_size_inches(15,5)
Opening raw-browser...
dset_mne_reffilt = dset_mne_ref.copy().filter(l_freq=300,h_freq = 6000)
Filtering raw data in 1 contiguous segment Setting up band-pass filter from 3e+02 - 6e+03 Hz FIR filter parameters --------------------- Designing a one-pass, zero-phase, non-causal bandpass filter: - Windowed time-domain design (firwin) method - Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation - Lower passband edge: 300.00 - Lower transition bandwidth: 75.00 Hz (-6 dB cutoff frequency: 262.50 Hz) - Upper passband edge: 6000.00 Hz - Upper transition bandwidth: 1500.00 Hz (-6 dB cutoff frequency: 6750.00 Hz) - Filter length: 1101 samples (0.044 sec)
fig = mne.viz.plot_raw(
dset_mne_reffilt.copy().pick_channels(['ch3']),
start=0.08,
duration = 0.02,
show=False,
scalings={'eeg':1000})
fig.set_size_inches(15,5)
Opening raw-browser...
Different approaches and algorithms for Spike Sorting. Here, we use SpikeInterface:
import spikeinterface.full as ss
Create a spikeinterface recording object
num_channels = 4
sampling_frequency = 25000 # in Hz
num_segments = 1
recording = ss.NumpyRecording(traces_list=[dset.T], sampling_frequency=sampling_frequency)
Plot first 5 seconds of data
#%% Plot first 5 seconds
w_ts = ss.plot_timeseries(recording, time_range=(0, 5))
fig = plt.gcf()
fig.set_size_inches(15,10)
fig.suptitle('Raw signal')
fig.tight_layout()
Preprocess the data:
# Filter the recording
recording_flt = ss.bandpass_filter(recording,freq_min=300, freq_max=6000)
# Re-reference
recording_fltref = ss.common_reference(recording_flt,reference='global',operator='median')
Plot the processed data
# Plot
w_ts = ss.plot_timeseries(recording_fltref, time_range=(0, 5))
fig = plt.gcf()
fig.set_size_inches(15,10)
fig.suptitle('Filtered & re-referenced')
fig.tight_layout()
Pick a channel for spike-sorting
Note: spike sorting can be performed for multiple channels. It is even possible to try to identify units that are visible in multiple channels (if electrodes were placed close to each other)
recording_fltref_chn = recording_fltref.channel_slice([0])
Define the electrode ("probe") that was used:
from probeinterface import generate_linear_probe
from probeinterface.plotting import plot_probe, plot_probe_group
from probeinterface import Probe, ProbeGroup
# create probe
linear_probe = generate_linear_probe(num_elec=1, ypitch=20)
linear_probe.set_device_channel_indices(0)
plot_probe(linear_probe, with_channel_index=True)
(<matplotlib.collections.PolyCollection at 0x7f05af0d3a60>, <matplotlib.collections.PolyCollection at 0x7f05af0e8d60>)
Assign probe to recording
recording_fltref_chn = recording_fltref_chn.set_probe(linear_probe)
Save recording (required for sorting)
recording_preprocessed = recording_fltref_chn.save(format='binary')
Use cache_folder=/tmp/spikeinterface_cache/tmp6f0tpjvj/T14XNWTJ write_binary_recording with n_jobs 1 chunk_size None
Run sorter:
sorting_TDC = ss.run_sorter(sorter_name = 'tridesclous',
recording=recording_preprocessed)
Report the result: hot many units?
print(sorting_TDC)
TridesclousSortingExtractor: 2 units - 1 segments - 25.0kHz
Extract the waveforms of all units
we_TDC = ss.WaveformExtractor.create(recording_preprocessed,
sorting_TDC, 'waveforms',
remove_if_exists=True)
we_TDC.set_params(ms_before=3., ms_after=4., max_spikes_per_unit=500)
we_TDC.run_extract_waveforms(n_jobs=-1, chunk_size=30000)
Plot the waveforms of all units
ss.plot_unit_waveforms(we_TDC,unit_ids = sorting_TDC.unit_ids[:])
fig = plt.gcf()
fig.set_size_inches(15,10)
fig.suptitle('Waveforms of units')
Text(0.5, 0.98, 'Waveforms of units')
fig, ax = plt.subplots(figsize=(15,5))
for Ui in range(len(sorting_TDC.unit_ids)):
ax.plot(np.mean(we_TDC.get_waveforms(Ui),axis=0),label=str(Ui))
ax.legend()
fig.suptitle('Mean waveforms')
Text(0.5, 0.98, 'Mean waveforms')
Plot the activity of the units
ss.plot_rasters(sorting_TDC)
fig = plt.gcf()
fig.set_size_inches(15,5)
fig.suptitle('Single spikes in time per unit')
Text(0.5, 0.98, 'Single spikes in time per unit')
ss.plot_presence(sorting_TDC)
fig = plt.gcf()
fig.set_size_inches(15,5)
fig.suptitle('Spiking activity in time as density')
Text(0.5, 0.98, 'Spiking activity in time as density')
Plot auto- and cross-correlogram
ss.plot_crosscorrelograms(sorting_TDC, window_ms=300.0, bin_ms=5.0, symmetrize=True)
fig = plt.gcf()
fig.set_size_inches(15,10)
fig.suptitle('Auto-and Cross-correlogram')
Text(0.5, 0.98, 'Auto-and Cross-correlogram')
Assignment: what kind of information do the auto- and cross-correlograms represent?